/*
 * Copyright (c) 2018-2999 北京国电高科科技有限公司 All rights reserved.
 *
 * https://www.tqmall.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.gdgk.shop.api.controller;

import com.gdgk.shop.api.config.WxPayProperties;
import com.gdgk.shop.common.response.ServerResponseEntity;
import com.gdgk.shop.service.PayService;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Hidden;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author lanhai
 */
@Hidden
@RestController
@RequestMapping("/notice/pay")
@AllArgsConstructor
@Slf4j
public class PayNoticeController {
    /**
     * 小程序支付
     */
    private final WxPayProperties properties;
    private final PayService payService;

    @RequestMapping("/order")
    public String submit(HttpServletRequest requestBody, HttpServletResponse response) throws Exception {
        log.info("进入回调url");
        // 报文body
        String body = getRequestBody(requestBody);
        // 微信支付平台证书的序列号，验签必须使用序列号对应的微信支付平台证书
        String paySerial = requestBody.getHeader("Wechatpay-Serial");
        // 签名中的随机数
        String payNonce = requestBody.getHeader("Wechatpay-Nonce");
        // 应答的微信支付签名
        String sign = requestBody.getHeader("Wechatpay-Signature");
        // 签名中的时间戳
        String timeStamp = requestBody.getHeader("Wechatpay-Timestamp");
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(paySerial)
                .nonce(payNonce)
                .signature(sign)
                .timestamp(timeStamp)
                .body(body)
                .build();
        // 初始化了 RSAAutoCertificateConfig
        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                .merchantId(properties.getMchId())
//                .privateKeyFromPath(properties.getKeyPath())
                .privateKey(properties.getPrivateKey())
                .merchantSerialNumber(properties.getSerial())
                .apiV3Key(properties.getApiV3Key())
                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);
        boolean bizStatus = true;
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            String payNo = transaction.getOutTradeNo();
            String bizPayNo = transaction.getTransactionId();
            // 根据内部订单号更新order settlement
            payService.paySuccess(payNo, bizPayNo);
        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
            log.error("微信支付回调签名验证失败!");
            response.setStatus(401);
            return "{" +
                    '"' + "code" + '"' + ":" + '"' + "FAIL" + '"' + " " +
                    '"' + "message" + '"' + ":" + '"' + "失败" + '"' +
                    "}";
        } catch (Exception e) {
            bizStatus = false;
        }
        // 如果处理失败，应返回 4xx/5xx 的状态码，例如 500 INTERNAL_SERVER_ERROR
        if (!bizStatus) {
            response.setStatus(500);
            return "{" +
                    '"' + "code" + '"' + ":" + '"' + "FAIL" + '"' + " " +
                    '"' + "message" + '"' + ":" + '"' + "失败" + '"' +
                    "}";
        } else {
            response.setStatus(200);
            return "{" +
                    '"' + "code" + '"' + ":" + '"' + "SUCCESS" + '"' + " " +
                    '"' + "message" + '"' + ":" + '"' + "成功" + '"' +
                    "}";
        }

    }

    /**
     * 读取请求数据流
     *
     * @param request
     * @return
     */
    private String getRequestBody(HttpServletRequest request) {

        StringBuffer sb = new StringBuffer();

        try (ServletInputStream inputStream = request.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        ) {
            String line;

            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            // 读取数据流异常
            System.out.println("读取数据流异常");
        }

        return sb.toString();

    }
}
